package learn.jackjson.use;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;








import java.util.Set;

import org.junit.Test;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import learn.jackjson.bean.Article;
import learn.jackjson.bean.Author;
import learn.jackjson.bean.Role;
import learn.jackjson.bean.Student;
import learn.jackjson.bean.User;
import learn.jackjson.util.Jacksons;

public class Demo1 {
	
	
	    /**
	     * @throws IOException 
	     * @throws JsonMappingException 
	     * @throws JsonGenerationException 
	    * @Title: 2 json
	    * @Description: 简单转换:在jackJson中，read为json2Object write 为object2Json
	    * @param     
	    * @return void    
	    * @throws
	    */
	@Test
	public void simple2Json() throws  IOException{
		//Pojo 2 json
		ObjectMapper mapper = new ObjectMapper(); 
		Student student=new Student();
		student.setName("nsl");
		student.setCreateDate(new Date());
		student.getBookNameList().add("book1");
		student.getBookNameList().add("book2");
		student.getBookNameList().add("book3");
		//格式话日期
		//mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); 
		String json = mapper.writeValueAsString(student); 
		System.out.println("student ="+ json);
		System.out.println("**************************");
		System.out.println();
		
		//list<String> 2 json
		List<String> stringList=new ArrayList<String>();
		stringList.add("aa");
		stringList.add("bb");
		stringList.add("cc");
		json=mapper.writeValueAsString(stringList);
		System.out.println("List<String> =" +json);
		System.out.println("**************************");
		System.out.println();
		
		//Map<String,String> 2 json
		Map<String,String> stringMap=new HashMap<String,String>();
		stringMap.put("aa","1");
		stringMap.put("bb","2");
		stringMap.put("cc","1");
		json=mapper.writeValueAsString(stringMap);
		System.out.println("Map<String,String> =" +json);
		System.out.println("**************************");
		System.out.println();
		
		//PojoWithCollection 2 json
		List<User> userList=new ArrayList<User>();
		User user1=new User();
		user1.setIsDelete(1);
		user1.setLoginName("nsl");
		Role role1=new Role("admin", 1);
		Role role2=new Role("guest", 2);
		user1.getRoleList().add(role1);
		user1.getRoleList().add(role2);
		User user2=new User();
		user1.setIsDelete(2);
		user1.setLoginName("djj");
		user2.getRoleList().add(role1);
		userList.add(user1);
		userList.add(user2);
		mapper.enable(SerializationFeature.INDENT_OUTPUT);
		json=mapper.writeValueAsString(userList);
		//缩进格式
	
		System.out.println("collect of User = " + json);
	}
	
	@Test
	public void json2Objcet() throws JsonParseException, JsonMappingException, IOException{
		//转对象
		  String json = "{\"userID\":1,\"LoginName\":\"\",\"Truename\":"
		  		+ "\"超级\",\"Nickname\":null,\"LoginPwd\":\"E10ADC3949BA59ABBE56E057F20F883E\","
		  		+ "\"QQ\":\"\",\"phone\":\"\",\"Email\":null,\"Remark\":\"\",\"Account_Non_Locked\":0,\"Telelephone\":null,\"IsDelete\":0}";  
		  ObjectMapper mapper = new ObjectMapper(); 
		// to prevent exception when encountering unknown property:
		  mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
		// to allow serialization of "empty" POJOs (no properties to serialize)
		// (without this setting, an exception is thrown in those cases)
		mapper.enable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
		// to allow coercion of JSON empty String ("") to null Object value:
		// Feature that can be enabled to allow JSON empty String value ("") to be bound to POJOs as null.  
		// 只针对pojo起作用
		//http://stackoverflow.com/questions/22688713/jackson-objectmapper-deserializationconfig-feature-accept-empty-string-as-null-o
		//mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
		  User user=mapper.readValue(json, User.class);
		  System.out.println(user);
		  
		 //转集合
        String josn2 = "[{\"UserID\":1,\"LoginName\":\"唐工\",\"Truename\":\"超级\",\"Nickname\":null,\"LoginPwd\":\"E10ADC3949BA59ABBE56E057F20F883E\",\"QQ\":\"\",\"Phone\":\"\",\"Email\":null,\"Remark\":\"\",\"Account_Non_Locked\":0,\"Telelephone\":null,\"IsDelete\":0}]";  
        JavaType javaType = mapper.getTypeFactory().constructParametricType(  
                List.class, User.class);  
        List<User> me = mapper.readValue(josn2, javaType);  
        System.out.println("转集合me:" + me);  
		  
     // 对象里有 集合 转换  
        String josn3 = "{\"UserID\":1,\"LoginName\":\"唐工\",\"Truename\":\"超级\",\"Nickname\":null,\"LoginPwd\":\"E10ADC3949BA59ABBE56E057F20F883E\",\"QQ\":\"\",\"Phone\":\"\",\"Email\":null,\"Remark\":\"\",\"Account_Non_Locked\":0,\"Telelephone\":null,\"IsDelete\":0,\"roleList\":[{\"roleid\":0,\"name\":\"超级管理员\",\"Show_Name\":\"超级管理员\",\"remark\":null,\"type\":1}]}";  
  
        User u3 = mapper.readValue(josn3, User.class); // 简单方式  
        // User u3=new Main<User>().jsonConverObject(josn3, User.class); 流方式  
        System.out.println("转对象里有集合u3:" + u3);  
  
        // 集合 对象 集合 转换  
        String josn4 = "[{\"UserID\":1,\"LoginName\":\"唐工\",\"Truename\":\"超级\",\"Nickname\":null,\"LoginPwd\":\"E10ADC3949BA59ABBE56E057F20F883E\",\"QQ\":\"\",\"Phone\":\"\",\"Email\":null,\"Remark\":\"\",\"Account_Non_Locked\":0,\"Telelephone\":null,\"IsDelete\":0,\"RoleList\":[{\"Roleid\":0,\"Name\":\"超级管理员\",\"Show_Name\":\"超级管理员\",\"Remark\":null,\"Type\":1}]},{\"UserID\":2,\"LoginName\":\"唐工\",\"Truename\":\"超级\",\"Nickname\":null,\"LoginPwd\":\"E10ADC3949BA59ABBE56E057F20F883E\",\"QQ\":\"\",\"Phone\":\"\",\"Email\":null,\"Remark\":\"\",\"Account_Non_Locked\":0,\"Telelephone\":null,\"IsDelete\":0,\"RoleList\":[{\"Roleid\":0,\"Name\":\"超级管理员\",\"Show_Name\":\"超级管理员\",\"Remark\":null,\"Type\":1}]}]";  
        JavaType javaType4 = mapper.getTypeFactory().constructParametricType(  
                List.class, User.class);  
        List<User> list = mapper.readValue(josn4, javaType4);  
        System.out.println("集合里是对象 对象里有集合转换:" + list);  
		  
	}
	
	//循环引用
/*	jackson中的@JsonBackReference和@JsonManagedReference，
	以及@JsonIgnore均是为了解决对象中存在双向引用导致的无限递归（infinite recursion）问题。这些标注均可用在属性或对应的get、set方法中。 

	@JsonBackReference和@JsonManagedReference：这两个标注通常配对使用，通常用在父子关系中。
	@JsonBackReference标注的属性在序列化（serialization，即将对象转换为json数据）时，会被忽略（即结果中的json数据不包含该属性的内容）。
	@JsonManagedReference标注的属性则会被序列化。在序列化时，@JsonBackReference的作用相当于@JsonIgnore，
	此时可以没有@JsonManagedReference。但在反序列化（deserialization，即json数据转换为对象）时，
	如果没有@JsonManagedReference，则不会自动注入@JsonBackReference标注的属性（被忽略的父或子）；
	如果有@JsonManagedReference，则会自动注入自动注入@JsonBackReference标注的属性。 

	@JsonIgnore：直接忽略某个属性，以断开无限递归，序列化或反序列化均忽略。
	当然如果标注在get、set方法中，则可以分开控制，序列化对应的是get方法，反序列化对应的是set方法。
	在父子关系中，当反序列化时，@JsonIgnore不会自动注入被忽略的属性值（父或子），这是它跟@JsonBackReference和@JsonManagedReference最大的区别。
	
	
	动态过滤属性，这个比较麻烦。
	有3个方法。
	
	1.使用@JsonFilter注解
	使用方法为先给ObjectMapper添加一个filter，然后还要在需要过滤的类上加@JsonFilter("filterName")注解。
	
	比如说要过滤User 上的name属性，先
	Jacksons.me().filter("myFilter", "name").readAsString(user)，具体看Jacksons代码。并在User类上加@JsonFilter("myFilter")。
	有点不爽的是如果用另外一个没有添加该filter的ObjectMapper解析的话会报错。
	如果这个User类已经添加了@JsonFilter("myFilter")注解，但在另外一个地方又要解析它并不想过滤name 属性，那只能是
	Jacksons.me().filter("myFilter", "")，然后在读出来。
	
	
	2.定义一个接口或类先, 在该类上添加@JsonIgnoreProperties("name"), 然后在ObjectMapper的配置项上添加混入注解

	输出为:String mixInUser = Jacksons.me().addMixInAnnotations(User.class, MixInUser.class).readAsString(user);

	System.out.println(mixInUser);
	
	3.方法就是将要忽略的字段赋值为null 然后让jackson转换json的时候忽略值为null的属性...这样应该就达到了你说的效果.
	
	*/
	@Test
	public void cycleTest(){
		Author author = new Author();  
        author.setName("chris");  
        author.setCreateDate(new Date());  
        Article article = new Article();  
        article.setTitle("title");  
        article.setUser(author);  
        Set<Article> articles = new HashSet<Article>();  
        author.setArticles(articles);  
        
        String userJson = Jacksons.me().filter("myFilter", "name").readAsString(author);  
        String articleJson = Jacksons.me().readAsString(article);  
        System.out.println(userJson);  
        System.out.println(articleJson);  
	}
	
	@Test
	public void testIgnore() throws JsonProcessingException{
		Author author = new Author();  
        author.setName("chris");  
        author.setCreateDate(new Date());  
        Article article = new Article();  
        article.setTitle("title");  
        article.setUser(author);  
        Set<Article> articles = new HashSet<Article>();  
        author.setArticles(articles);  
        ObjectMapper mapper = new ObjectMapper(); 
        mapper.setSerializationInclusion(Include.NON_NULL);
	      //通过该方法对mapper对象进行设置，所有序列化的对象都将按改规则进行系列化
	      //Include.Include.ALWAYS 默认
	      //Include.NON_DEFAULT 属性为默认值不序列化
	      //Include.NON_EMPTY 属性为 空（“”） 或者为 NULL 都不序列化
	      //Include.NON_NULL 属性为NULL 不序列化 
        author.setArticles(null);
        String jsonString=mapper.writeValueAsString(author);
        System.out.println(jsonString);
        
	}
	
}
